<!DOCTYPE html>
<html lang="zh-Hans">

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="x5-fullscreen" content="true">
<meta name="full-screen" content="yes">
<meta name="theme-color" content="#317EFB" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=0" name="viewport">
<meta name="description" content="一，开发环境搭建1.创建数据库 reggie 引入表 2.创建一个Maven项目name：reggie_take_out  GroupId:com.yiyi 3.引入依赖pom.xml 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758">
<meta property="og:type" content="article">
<meta property="og:title" content="吉瑞外卖开发详解">
<meta property="og:url" content="https://big-ttong/myblog.git/2023/07/21/%E7%91%9E%E5%90%89%E5%A4%96%E5%8D%96%E4%BB%A3%E7%A0%81%E8%AF%A6%E8%A7%A3/index.html">
<meta property="og:site_name" content="欢迎访问我的blog">
<meta property="og:description" content="一，开发环境搭建1.创建数据库 reggie 引入表 2.创建一个Maven项目name：reggie_take_out  GroupId:com.yiyi 3.引入依赖pom.xml 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758">
<meta property="og:locale">
<meta property="article:published_time" content="2023-07-21T01:10:23.093Z">
<meta property="article:modified_time" content="2023-08-01T00:18:57.797Z">
<meta property="article:author" content="洪汉桐">
<meta name="twitter:card" content="summary">


<title >吉瑞外卖开发详解</title>

<!-- Favicon -->

    <link href='/myblog/log.svg?v=2.0.9' rel='icon' type='image/png' sizes='16x16' ></link>


    <link href='/myblog/log.svg?v=2.0.9' rel='icon' type='image/png' sizes='32x32' ></link>


    <link href='/myblog/log.svg?v=2.0.9' rel='apple-touch-icon' sizes='180x180' ></link>


    <link href='/myblog/site.webmanifest' rel='manifest' ></link>


<!-- Plugin -->




    
<link rel="stylesheet" href="/myblog/css/plugins/bootstrap.row.css">

    
<link rel="stylesheet" href="https://unpkg.com/locomotive-scroll@4.1.4/dist/locomotive-scroll.min.css">

    
<link rel="stylesheet" href="https://unpkg.com/@fancyapps/ui@4.0/dist/fancybox.css">

    
    




<!-- Icon -->

    
<link rel="stylesheet" href="/myblog/css/plugins/font-awesome.min.css">




<!-- Variable -->
<script>window.ASYNC_CONFIG = {"hostname":"big-ttong","author":"洪汉桐","root":"/myblog/","typed_text":["extraordinary"],"theme_version":"2.0.9","theme":{"switch":true,"default":"style-light"},"favicon":{"logo":"log.svg","icon16":"log.svg","icon32":"log.svg","appleTouchIcon":"log.svg","webmanifest":"/site.webmanifest","visibilitychange":true,"hidden":"failure.ico","showText":"(/≧▽≦/)咦！又好了！","hideText":"(●—●)喔哟，崩溃啦！"},"i18n":{"placeholder":"搜索文章...","empty":"找不到您查询的内容: ${query}","hits":"找到 ${hits} 条结果","hits_time":"找到 ${hits} 条结果（用时 ${time} 毫秒）","author":"本文作者：","copyright_link":"本文链接：","copyright_license_title":"版权声明：","copyright_license_content":"本博客所有文章除特别声明外，均默认采用 undefined 许可协议。","copy_success":"复制成功","copy_failure":"复制失败","open_read_mode":"进入阅读模式","exit_read_mode":"退出阅读模式","notice_outdate_message":"距离上次更新已经 undefined 天了, 文章内容可能已经过时。","just":"刚刚","min":"分钟前","hour":"小时前","day":"天前","month":"个月前"},"swup":false,"plugin":{"flickr_justified_gallery":"https://unpkg.com/flickr-justified-gallery@latest/dist/fjGallery.min.js"},"icons":{"sun":"far fa-sun","moon":"far fa-moon","play":"fas fa-play","email":"far fa-envelope","next":"fas fa-arrow-right","calendar":"far fa-calendar-alt","clock":"far fa-clock","user":"far fa-user","back_top":"fas fa-arrow-up","close":"fas fa-times","search":"fas fa-search","reward":"fas fa-hand-holding-usd","user_tag":"fas fa-user-alt","toc_tag":"fas fa-th-list","read":"fas fa-book-reader","arrows":"fas fa-arrows-alt-h","double_arrows":"fas fa-angle-double-down","copy":"fas fa-copy"},"icontype":"font","highlight":{"plugin":"highlighjs","theme":true,"copy":true,"lang":true,"title":"default","height_limit":200},"notice_outdate":{"enable":true,"style":"flat","limit_day":365,"position":"top"}};</script>
<script id="async-page-config">window.PAGE_CONFIG = {"isPost":true,"isHome":false,"postUpdate":"2023-08-01 08:18:57"};</script>

<!-- Theme mode css -->
<link data-swup-theme rel="stylesheet" href="/myblog/css/index.css?v=2.0.9" id="trm-switch-style">
<script>
    let defaultMode = ASYNC_CONFIG.theme.default !=='auto' ?  ASYNC_CONFIG.theme.default : (window.matchMedia("(prefers-color-scheme: light)").matches ? 'style-light' : 'style-dark')
    let catchMode = localStorage.getItem('theme-mode') || defaultMode;
    let type = catchMode === 'style-dark' ? 'add' : 'remove';
    document.documentElement.classList[type]('dark')
</script>

<!-- CDN -->


    
    



<!-- Site Analytics -->
 
<meta name="generator" content="Hexo 6.3.0"></head>

<body>

  <!-- app wrapper -->
  <div class="trm-app-frame">

    <!-- page preloader -->
    <div class="trm-preloader">
    <div class="trm-holder">
        <div class="preloader">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
</div>
    <!-- page preloader end -->

    <!-- change mode preloader -->
    <div class="trm-mode-swich-animation-frame">
    <div class="trm-mode-swich-animation">
        <i class="i-sun"><i class="iconfont far fa-sun"></i></i>
        <div class="trm-horizon"></div>
        <i class="i-moon"><i class="iconfont far fa-moon"></i></i>
    </div>
</div>
    <!-- change mode preloader end -->

      <!-- scroll container -->
      <div id="trm-dynamic-content" class="trm-swup-animation">
        <div id="trm-scroll-container" class="trm-scroll-container" data-scroll-container style="opacity: 0">
          <div data-scroll-section id="content" class="trm-scroll-section">

            <div class="locomotive-scroll__sticky-target" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none;"></div>

            <!-- top bar -->
            <header class="trm-top-bar" data-scroll data-scroll-sticky data-scroll-target=".locomotive-scroll__sticky-target" data-scroll-offset="-10">
	<div class="container">
		<div class="trm-left-side">
			<!-- logo -->
<a href="/myblog/" class="trm-logo-frame trm-anima-link">
    
        <img alt="logo" src="/myblog/log.svg">
    
    
        <div class="trm-logo-text">
            洪<span>汉桐</span>
        </div>
    
</a>
<!-- logo end -->
		</div>
		<div class="trm-right-side">
			<!-- menu -->
<div class="trm-menu">
    <nav>
        <ul>
            
            <li class="menu-item-has-children ">
                <a  href="/myblog/" target="">
                    首页
                </a>
                
            </li>
            
            <li class="menu-item-has-children ">
                <a  href="/myblog/archives/" target="">
                    归档
                </a>
                
            </li>
            
        </ul>
    </nav>
</div>
<!-- menu end -->
			
    <!-- mode switcher place -->
    <div class="trm-mode-switcher-place">
        <div class="trm-mode-switcher">
            <i class="iconfont far fa-sun"></i>
            <input class="tgl tgl-light" id="trm-swich" type="checkbox">
            <label class="trm-swich" for="trm-swich"></label>
            <i class="iconfont far fa-moon"></i>
        </div>
    </div>
    <!-- mode switcher place end -->

			
		</div>
		<div class="trm-menu-btn">
			<span></span>
		</div>
	</div>
</header>
            <!-- top bar end -->

            <!-- body -->
            
<div class="trm-content-start">
    <!-- banner -->
    <div class="trm-banner" data-scroll data-scroll-direction="vertical">
    
    <!-- banner cover -->
    <img style="object-position:top;object-fit:cover;" alt="banner" class="trm-banner-cover" data-scroll data-scroll-direction="vertical" data-scroll-speed="-3" src="/myblog/img/banner.png">
    <!-- banner cover end -->
    

    <!-- banner content -->
    <div class="trm-banner-content trm-overlay">
        <div class="container" data-scroll data-scroll-direction="vertical" data-scroll-speed="0">
            <div class="row">
                
                <div class="col-lg-4"></div>
                
                <div class="col-lg-8">

                    <!-- banner title -->
                    <div class="trm-banner-text ">
                        <div class="trm-label trm-mb-20">
                            NEWS LETTER
                        </div>
                        <h1 class="trm-mb-30 trm-hsmb-font">
                            吉瑞外卖开发详解
                        </h1>

                        
                            <ul class="trm-breadcrumbs trm-label">
                                <li>
                                    <a href="/myblog/" class="trm-anima-link">Home</a>
                                </li>
                                <li>
                                    <span>
                                        2023
                                    </span
                                ></li>
                            </ul>
                        
                    </div>
                    <!-- banner title end -->

                    <!-- scroll hint -->
                    <a href="#about-triger" data-scroll-to="#about-triger" data-scroll-offset="-130" class="trm-scroll-hint-frame">
                        <div class="trm-scroll-hint"></div>
                        <span class="trm-label">Scroll down</span>
                    </a>
                    <!-- scroll hint end -->

                </div>
            </div>
        </div>
    </div>
    <!-- banner content end -->
</div>
    <!-- banner end -->
    <div class="container">
        <div class="row">
            
                <div id="page-sidebar" class="col-lg-4 hidden-sm">
                    <!-- main card -->
                    

<div class="trm-main-card-frame trm-sidebar">
    <div class="trm-main-card" data-scroll data-scroll-repeat data-scroll-sticky data-scroll-target=".locomotive-scroll__sticky-target" data-scroll-offset="60"> 
    
        <div class="trm-user-tabs" id="sidebar-tabs">
           <div class="trm-tabs-nav trm-mb-40" id="trm-tabs-nav">
                <div data-to="tabs-user" class="trm-tabs-nav-item">
                    <i class="iconfont fas fa-user-alt"></i>
                </div>
                <div data-to="tabs-toc" class="trm-tabs-nav-item active">
                    <i class="iconfont fas fa-th-list"></i>
                </div>
           </div>
            <div name="tabs-user" class="trm-tabs-item">
                <!-- card header -->
<div class="trm-mc-header">
    <div class="trm-avatar-frame trm-mb-20">
        <img alt="Avatar" class="trm-avatar trm-light-icon" src="/myblog/img/profilephoto2.jpg"> <img alt="Avatar" class="trm-avatar trm-dark-icon" src="/myblog/img/profilephoto1.jpg">
    </div>
    <h5 class="trm-name trm-mb-15">
        洪汉桐
    </h5>
    
        <div class="trm-label">
            I`m
            <span class="trm-typed-text">
                <!-- Words for theme.user.typedText -->
            </span>
        </div>
    
</div>
<!-- card header end -->
                <!-- sidebar social -->

<div class="trm-divider trm-mb-40 trm-mt-40"></div>
<div class="trm-social">
    
        <a href="https://github.com" title="Github" rel="nofollow" target="_blank">
            <i class="iconfont fab fa-github"></i>
        </a>
    
</div>

<!-- sidebar social end -->
                <!-- info -->
<div class="trm-divider trm-mb-40 trm-mt-40"></div>
<ul class="trm-table trm-mb-20">
    
        <li>
            <div class="trm-label">
                地址:
            </div>
            <div class="trm-label trm-label-light">
                河北雄安
            </div>
        </li>
    
        <li>
            <div class="trm-label">
                年龄:
            </div>
            <div class="trm-label trm-label-light">
                19
            </div>
        </li>
    
</ul>
<!-- info end -->

                
    <div class="trm-divider trm-mb-40 trm-mt-40"></div>
    <!-- action button -->
    <div class="text-center">
        <a href="mailto:2067046599@qq.com" class="trm-btn">
            联系我
            <i class="iconfont far fa-envelope"></i>
        </a>
    </div>
    <!-- action button end -->

            </div>
            <div name="tabs-toc" class="trm-tabs-item active">
                <div class="post-toc">
    <ol class="toc"><li class="toc-item toc-level-1"><a rel="nofollow" class="toc-link" href="#一，开发环境搭建"  data-scroll-to="#一，开发环境搭建"><span class="toc-number">1.</span> <span class="toc-text">一，开发环境搭建</span></a></li><li class="toc-item toc-level-1"><a rel="nofollow" class="toc-link" href="#二，后台系统功能实现"  data-scroll-to="#二，后台系统功能实现"><span class="toc-number">2.</span> <span class="toc-text">二，后台系统功能实现</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#员工管理页面"  data-scroll-to="#员工管理页面"><span class="toc-number">2.1.</span> <span class="toc-text">员工管理页面</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#登录功能的实现"  data-scroll-to="#登录功能的实现"><span class="toc-number">2.1.1.</span> <span class="toc-text">登录功能的实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#退出功能的实现"  data-scroll-to="#退出功能的实现"><span class="toc-number">2.1.2.</span> <span class="toc-text">退出功能的实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#新增员工功能的实现"  data-scroll-to="#新增员工功能的实现"><span class="toc-number">2.1.3.</span> <span class="toc-text">新增员工功能的实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#员工分页查询功能实现"  data-scroll-to="#员工分页查询功能实现"><span class="toc-number">2.1.4.</span> <span class="toc-text">员工分页查询功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#员工账号状态功能实现"  data-scroll-to="#员工账号状态功能实现"><span class="toc-number">2.1.5.</span> <span class="toc-text">员工账号状态功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#编辑员工信息功能实现"  data-scroll-to="#编辑员工信息功能实现"><span class="toc-number">2.1.6.</span> <span class="toc-text">编辑员工信息功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#公共字段自动填充功能的实现"  data-scroll-to="#公共字段自动填充功能的实现"><span class="toc-number">2.1.7.</span> <span class="toc-text">公共字段自动填充功能的实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#新增分类功能实现-Category-页面"  data-scroll-to="#新增分类功能实现-Category-页面"><span class="toc-number">2.1.8.</span> <span class="toc-text">新增分类功能实现(Category 页面)</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#分页查询功能实现"  data-scroll-to="#分页查询功能实现"><span class="toc-number">2.1.9.</span> <span class="toc-text">分页查询功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#删除分类功能实现"  data-scroll-to="#删除分类功能实现"><span class="toc-number">2.1.10.</span> <span class="toc-text">删除分类功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#修改分类功能实现"  data-scroll-to="#修改分类功能实现"><span class="toc-number">2.1.11.</span> <span class="toc-text">修改分类功能实现</span></a></li></ol></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#菜品管理"  data-scroll-to="#菜品管理"><span class="toc-number">2.2.</span> <span class="toc-text">菜品管理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#文件的上传与下载"  data-scroll-to="#文件的上传与下载"><span class="toc-number">2.2.1.</span> <span class="toc-text">文件的上传与下载</span></a></li></ol></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#菜品管理-1"  data-scroll-to="#菜品管理-1"><span class="toc-number">2.3.</span> <span class="toc-text">菜品管理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#需求分析"  data-scroll-to="#需求分析"><span class="toc-number">2.3.1.</span> <span class="toc-text">需求分析</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#新增菜品"  data-scroll-to="#新增菜品"><span class="toc-number">2.3.2.</span> <span class="toc-text">新增菜品</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#菜品信息分页查询"  data-scroll-to="#菜品信息分页查询"><span class="toc-number">2.3.3.</span> <span class="toc-text">菜品信息分页查询</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#编辑菜品信息"  data-scroll-to="#编辑菜品信息"><span class="toc-number">2.3.4.</span> <span class="toc-text">编辑菜品信息</span></a></li></ol></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#套餐管理功能的实现"  data-scroll-to="#套餐管理功能的实现"><span class="toc-number">2.4.</span> <span class="toc-text">套餐管理功能的实现</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#添加套餐菜品的选择复选"  data-scroll-to="#添加套餐菜品的选择复选"><span class="toc-number">2.4.1.</span> <span class="toc-text">添加套餐菜品的选择复选</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#添加套餐菜品的功能实现"  data-scroll-to="#添加套餐菜品的功能实现"><span class="toc-number">2.4.2.</span> <span class="toc-text">添加套餐菜品的功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#套餐管理页面的显示功能实现list"  data-scroll-to="#套餐管理页面的显示功能实现list"><span class="toc-number">2.4.3.</span> <span class="toc-text">套餐管理页面的显示功能实现list</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#删除套餐管理功能实现"  data-scroll-to="#删除套餐管理功能实现"><span class="toc-number">2.4.4.</span> <span class="toc-text">删除套餐管理功能实现</span></a></li></ol></li><li class="toc-item toc-level-2"><a rel="nofollow" class="toc-link" href="#短信发送"  data-scroll-to="#短信发送"><span class="toc-number">2.5.</span> <span class="toc-text">短信发送</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#引入框架-Mapper-Service-ServiceImpl-Controller-（User）"  data-scroll-to="#引入框架-Mapper-Service-ServiceImpl-Controller-（User）"><span class="toc-number">2.5.1.</span> <span class="toc-text">引入框架 Mapper Service ServiceImpl Controller （User）</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#改进用户端的登陆状态（与管理端类似）"  data-scroll-to="#改进用户端的登陆状态（与管理端类似）"><span class="toc-number">2.5.2.</span> <span class="toc-text">改进用户端的登陆状态（与管理端类似）</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#短信发送验证码功能实现"  data-scroll-to="#短信发送验证码功能实现"><span class="toc-number">2.5.3.</span> <span class="toc-text">短信发送验证码功能实现</span></a></li><li class="toc-item toc-level-3"><a rel="nofollow" class="toc-link" href="#验证码填写完成登录功能的实现"  data-scroll-to="#验证码填写完成登录功能的实现"><span class="toc-number">2.5.4.</span> <span class="toc-text">验证码填写完成登录功能的实现</span></a></li></ol></li></ol></li></ol>
</div>
            </div>
        </div>
    
    </div>
</div>
                    <!-- main card end -->
                </div>
            
            <div id="page-content" class="col-lg-8">
                <div class="trm-content" id="trm-content">
                    <div data-scroll data-scroll-repeat data-scroll-offset="500" id="about-triger"></div>

                    <div id="post-info" class="row hidden-sm">
    <div class="col-sm-4">
        <div class="trm-card trm-label trm-label-light text-center">
            <i class="iconfont far fa-calendar-alt trm-icon"></i><br>
            07/21
        </div>
    </div>
    <div class="col-sm-4">
        <div class="trm-card trm-label trm-label-light text-center">
            <i class="iconfont far fa-clock trm-icon"></i><br>
            09:10
        </div>
    </div>
    <div class="col-sm-4">
        <div id="post-author" class="trm-card trm-label trm-label-light text-center">
            <i class="iconfont far fa-user trm-icon"></i><br>
            洪汉桐
        </div>
    </div>
</div>
<div class="trm-card ">
    <article id="article-container" class="trm-publication">
    <h1 id="一，开发环境搭建"><a href="#一，开发环境搭建" class="headerlink" title="一，开发环境搭建"></a>一，开发环境搭建</h1><p>1.创建数据库 reggie 引入表</p>
<p>2.创建一个Maven项目name：reggie_take_out  GroupId:com.yiyi</p>
<p>3.引入依赖pom.xml</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="line">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;</span><br><span class="line">         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span><br><span class="line">         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;</span><br><span class="line">    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;</span><br><span class="line">    &lt;parent&gt;</span><br><span class="line">        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">        &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;</span><br><span class="line">        &lt;version&gt;2.4.5&lt;/version&gt;</span><br><span class="line">        &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt;</span><br><span class="line">    &lt;/parent&gt;</span><br><span class="line">    &lt;groupId&gt;org.example&lt;/groupId&gt;</span><br><span class="line">    &lt;artifactId&gt;reggie_take_out&lt;/artifactId&gt;</span><br><span class="line">    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;</span><br><span class="line">    &lt;properties&gt;</span><br><span class="line">        &lt;java.version&gt;1.8&lt;/java.version&gt;</span><br><span class="line">    &lt;/properties&gt;</span><br><span class="line">    &lt;dependencies&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter&lt;/artifactId&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;</span><br><span class="line">            &lt;scope&gt;test&lt;/scope&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;</span><br><span class="line">            &lt;scope&gt;compile&lt;/scope&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.baomidou&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;mybatis-plus-boot-starter&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;3.4.2&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;lombok&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1.18.20&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.alibaba&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;fastjson&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1.2.76&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;commons-lang&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;commons-lang&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;2.6&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;mysql&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;</span><br><span class="line">            &lt;scope&gt;runtime&lt;/scope&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">        &lt;dependency&gt;</span><br><span class="line">            &lt;groupId&gt;com.alibaba&lt;/groupId&gt;</span><br><span class="line">            &lt;artifactId&gt;druid-spring-boot-starter&lt;/artifactId&gt;</span><br><span class="line">            &lt;version&gt;1.1.23&lt;/version&gt;</span><br><span class="line">        &lt;/dependency&gt;</span><br><span class="line"></span><br><span class="line">    &lt;/dependencies&gt;</span><br><span class="line"></span><br><span class="line">    &lt;build&gt;</span><br><span class="line">        &lt;plugins&gt;</span><br><span class="line">            &lt;plugin&gt;</span><br><span class="line">                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span><br><span class="line">                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;</span><br><span class="line">                &lt;version&gt;2.4.5&lt;/version&gt;</span><br><span class="line">            &lt;/plugin&gt;</span><br><span class="line">        &lt;/plugins&gt;</span><br><span class="line">    &lt;/build&gt;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&lt;/project&gt;</span><br></pre></td></tr></table></figure>

<p>4.创建application.yml，配置</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line">  port: 8080</span><br><span class="line">spring:</span><br><span class="line">  application:</span><br><span class="line">    name: reggie_take_out</span><br><span class="line">  datasource:</span><br><span class="line">    druid:</span><br><span class="line">      driver-class-name: com.mysql.cj.jdbc.Driver</span><br><span class="line">      url: jdbc:mysql://localhost:3306/reggie?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=convertToNull&amp;useSSL=false&amp;allowPublicKeyRetrieval=true</span><br><span class="line">      username: localhost</span><br><span class="line">      password: root</span><br><span class="line">mybatis-plus:</span><br><span class="line">  configuration:</span><br><span class="line">    #在映射实体或者属性时，将数据库中表名和字段名中的下划线去掉，按照驼峰命名法映射</span><br><span class="line">    map-underscore-to-camel-case: true</span><br><span class="line">    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl</span><br><span class="line">  global-config:</span><br><span class="line">    db-config:</span><br><span class="line">      id-type: ASSIGN_ID</span><br></pre></td></tr></table></figure>

<p>5.创建启动类在java下创建com.yiyi.reggie.ReggieApplication</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">@Slf4j   //日志的注解</span><br><span class="line">@SpringBootApplication  //启动注解</span><br><span class="line">public class ReggieApplication &#123;</span><br><span class="line">    public static void main(String[] args) &#123;</span><br><span class="line">        SpringApplication.run(ReggieApplication.class,args);</span><br><span class="line">        log.info(&quot;项目启动成功......&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<p>6.引入静态资源前端文件 backend（管理员）和front（前端展示）</p>
<p>7.设置静态资源映射，以扫描到引入的静态资源。创建com.yiyi.reggie.config.WebMvcConfig实体类</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">@Slf4j</span><br><span class="line">@Configuration</span><br><span class="line">public class WebMvcConfig extends WebMvcConfigurationSupport &#123;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 设置静态资源映射</span><br><span class="line">     * @param registry</span><br><span class="line">     *</span><br><span class="line">     **/</span><br><span class="line">    @Override</span><br><span class="line">    protected void addResourceHandlers(ResourceHandlerRegistry registry) &#123;</span><br><span class="line">        log.info(&quot;开始静态资源映射......&quot;);</span><br><span class="line">        registry.addResourceHandler(&quot;/backend/**&quot;).addResourceLocations(&quot;classpath:/backend/&quot;);</span><br><span class="line">        registry.addResourceHandler(&quot;/front/**&quot;).addResourceLocations(&quot;classpath:/front/&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h1 id="二，后台系统功能实现"><a href="#二，后台系统功能实现" class="headerlink" title="二，后台系统功能实现"></a>二，后台系统功能实现</h1><h2 id="员工管理页面"><a href="#员工管理页面" class="headerlink" title="员工管理页面"></a>员工管理页面</h2><h3 id="登录功能的实现"><a href="#登录功能的实现" class="headerlink" title="登录功能的实现"></a>登录功能的实现</h3><p>1.创建entity 对应 employee 的字段（映射关系）</p>
<p>2.创建 mapper service接口 serviceimpl类 controller</p>
<p>3.创建登录功能的各个 mapper service接口 serviceimpl类 controller</p>
<p>EmployeeMapper</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">@Mapper</span><br><span class="line">public interface EmployeeMapper extends BaseMapper&lt;Employee&gt; &#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>EmployeeService</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">public interface EmployeeService extends IService&lt;Employee&gt; &#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>EmployeeServiceImpl</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">@Service</span><br><span class="line">public class EmployeeServiceImpl extends ServiceImpl&lt;EmployeeMapper, Employee&gt; implements EmployeeService &#123;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>EmployeeController</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">@Slf4j</span><br><span class="line">@RestController</span><br><span class="line">@RequestMapping(&quot;/employee&quot;)</span><br><span class="line">public class EmployeeController &#123;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private EmployeeService employeeService;</span><br><span class="line">    </span><br><span class="line">    @PostMapping(&quot;/login&quot;)</span><br><span class="line">    public R&lt;Employee&gt; login(HttpServletRequest request, @RequestBody Employee employee)&#123;</span><br><span class="line">        // 1.将页面提交的密码password进行md5加密处理</span><br><span class="line">        // 2.根据页面提交的用户名username查询数据库</span><br><span class="line">        // 3.如果没有查询到则返回登录失败结果</span><br><span class="line">        // 4.密码对比，如果不一致则返回登录失败结果</span><br><span class="line">        // 5.查看员工状态，如果为已禁用状态，则返回员工已禁用结果</span><br><span class="line">        // 6.登陆成功，将员工id存入Session并返回登陆成功结果</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="存在问题"><a href="#存在问题" class="headerlink" title="存在问题"></a>存在问题</h4><p>用户如果不登陆，直接访问系统首页面，照样可以正常访问。<br>我们希望得到的效果应该是，登陆成功后才可以访问系统中的页面，如果没有登录则跳转到登录页面。</p>
<p>实现：使用过滤器或拦截器，在过滤器或拦截器中判断用户是否已经完成登录，如果没有登录则跳转到登录页面<br>我们采用过滤器的方法</p>
<p>1.创建 filter类 在com.yiyi.reggie.filter<br>2.实现</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line">package com.yiyi.reggie.filter;</span><br><span class="line"></span><br><span class="line">import com.alibaba.fastjson.JSON;</span><br><span class="line">import com.yiyi.reggie.commmon.R;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.util.AntPathMatcher;</span><br><span class="line"></span><br><span class="line">import javax.servlet.*;</span><br><span class="line">import javax.servlet.annotation.WebFilter;</span><br><span class="line">import javax.servlet.http.HttpServletRequest;</span><br><span class="line">import javax.servlet.http.HttpServletResponse;</span><br><span class="line">import java.io.IOException;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 检查用户是否已经完成登录</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line">@WebFilter(filterName = &quot;loginCheckFilter&quot;,urlPatterns = &quot;/*&quot;)</span><br><span class="line">@Slf4j</span><br><span class="line">public class LoginCheckFilter implements Filter &#123;</span><br><span class="line"></span><br><span class="line">    //路径匹配器，支持通配符 让index.html匹配</span><br><span class="line">    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException &#123;</span><br><span class="line">        HttpServletRequest request = (HttpServletRequest) servletRequest;</span><br><span class="line">        HttpServletResponse response = (HttpServletResponse) servletResponse;</span><br><span class="line"></span><br><span class="line">        // 1.获取本次请求的URI</span><br><span class="line">        String requestURI =  request.getRequestURI();</span><br><span class="line">        log.info(&quot;拦截请求：&#123;&#125;&quot;,requestURI);</span><br><span class="line"></span><br><span class="line">        //定义不需要处理的请求路径</span><br><span class="line">        String[] urls = new String[]&#123;</span><br><span class="line">                &quot;/employee/login&quot;,</span><br><span class="line">                &quot;/employee/logout&quot;,</span><br><span class="line">                &quot;/backend/**&quot;,</span><br><span class="line">                &quot;/front/**&quot;</span><br><span class="line">        &#125;;</span><br><span class="line">        // 2.判断本次请求是否需要处理</span><br><span class="line">        boolean check = check(urls,requestURI);</span><br><span class="line"></span><br><span class="line">        // 3.如果不需要处理，则直接放行</span><br><span class="line">        if (check)&#123;</span><br><span class="line">            log.info(&quot;本次请求&#123;&#125;不需要处理&quot;,requestURI);</span><br><span class="line">            filterChain.doFilter(request,response);</span><br><span class="line">            return;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        // 4.判断登录状态，如已登录，则直接放行</span><br><span class="line">        if(request.getSession().getAttribute(&quot;employee&quot;) != null)&#123;</span><br><span class="line">            log.info(&quot;用户已登录,用户id为:&#123;&#125;&quot;,request.getSession().getAttribute(&quot;employee&quot;));</span><br><span class="line">            filterChain.doFilter(request,response);</span><br><span class="line">            return;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        // 5.如果未登录，则返回未登录结果,通过输出流方式向客户端页面响应数据</span><br><span class="line">        log.info(&quot;用户未登录&quot;);</span><br><span class="line">        response.getWriter().write(JSON.toJSONString(R.error(&quot;NOTLOGIN&quot;)));</span><br><span class="line">        return;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 路径匹配，检查本次请求是否需要放行</span><br><span class="line">     * @param urls</span><br><span class="line">     * @param requestURI</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    public boolean check(String[] urls,String requestURI)&#123;</span><br><span class="line">        for (String url:urls) &#123;</span><br><span class="line">            boolean match =  PATH_MATCHER.match(url,requestURI);</span><br><span class="line">            if (match)&#123;</span><br><span class="line">                return true;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        return false;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="退出功能的实现"><a href="#退出功能的实现" class="headerlink" title="退出功能的实现"></a>退出功能的实现</h3><p>在EmployeeController中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">@PostMapping(&quot;/logout&quot;)</span><br><span class="line">private R&lt;String&gt; logout(HttpServletRequest request)&#123;</span><br><span class="line">    // 1.清理Session中保存的当前登陆员工的id</span><br><span class="line">    // 2.给出提示信息</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="新增员工功能的实现"><a href="#新增员工功能的实现" class="headerlink" title="新增员工功能的实现"></a>新增员工功能的实现</h3><p>首先得到的前端的axios 为employee，创建方法在EmployeeController中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"> /**</span><br><span class="line"> * 新增员工</span><br><span class="line"> * @param employee</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line">@PostMapping</span><br><span class="line">public R&lt;String&gt; save(HttpServletRequest request, @RequestBody Employee employee)&#123;</span><br><span class="line">    log.info(&quot;新增员工，员工信息：&#123;&#125;&quot;,employee.toString());</span><br><span class="line"></span><br><span class="line">    //设置初始密码123456，需要进行md5加密处理</span><br><span class="line">    employee.setPassword(DigestUtils.md5DigestAsHex(&quot;123456&quot;.getBytes()));</span><br><span class="line"></span><br><span class="line">    employee.setCreateTime(LocalDateTime.now());</span><br><span class="line">    employee.setUpdateTime(LocalDateTime.now());</span><br><span class="line"></span><br><span class="line">    //获得当前登录用户的id</span><br><span class="line">    Long empId = (Long) request.getSession().getAttribute(&quot;employee&quot;);</span><br><span class="line"></span><br><span class="line">    employee.setCreateUser(empId);</span><br><span class="line">    employee.setUpdateUser(empId);</span><br><span class="line"></span><br><span class="line">    employeeService.save(employee);</span><br><span class="line">    return R.success(&quot;新增员工成功&quot;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>然后经过测试发现如果用户名出现两次一样的，会报一个异常</p>
<h4 id="解决办法一"><a href="#解决办法一" class="headerlink" title="解决办法一"></a>解决办法一</h4><p>利用try{}catch{}</p>
<h4 id="解决办法二"><a href="#解决办法二" class="headerlink" title="解决办法二"></a>解决办法二</h4><p>写一个全局异常处理类器 &#x2F;common&#x2F;GlobalExceptionHandler</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"> /**</span><br><span class="line"> * 全局异常处理器</span><br><span class="line"> */</span><br><span class="line">@ControllerAdvice(annotations = &#123;RestController.class, Controller.class&#125;)</span><br><span class="line">@ResponseBody</span><br><span class="line">@Slf4j</span><br><span class="line">public class GlobalExceptionHandler &#123;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 异常处理方法</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)</span><br><span class="line">    public R&lt;String&gt; exceptionHandler(SQLIntegrityConstraintViolationException ex)&#123;</span><br><span class="line">        log.error(ex.getMessage());</span><br><span class="line"></span><br><span class="line">        if (ex.getMessage().contains(&quot;Duplicate entry&quot;))&#123;</span><br><span class="line">            String[] split = ex.getMessage().split(&quot; &quot;);</span><br><span class="line">            String msg = split[2] + &quot;已存在&quot;;</span><br><span class="line">            return R.error(msg);</span><br><span class="line">        &#125;</span><br><span class="line">        return R.error(&quot;未知错误&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="员工分页查询功能实现"><a href="#员工分页查询功能实现" class="headerlink" title="员工分页查询功能实现"></a>员工分页查询功能实现</h3><p>通过前端页面找到page的axios路径 &#x2F;page 传参（page，pageSize，name）</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"> /**</span><br><span class="line"> * 员工信息分页查询</span><br><span class="line"> * @param page</span><br><span class="line"> * @param pageSize</span><br><span class="line"> * @param name</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line">@GetMapping(&quot;/page&quot;)</span><br><span class="line">public R&lt;Page&gt; page(int page,int pageSize,String name)&#123;</span><br><span class="line">    log.info(&quot;page = &#123;&#125;,pageSize = &#123;&#125;,name= &#123;&#125;&quot;,page,pageSize,name);</span><br><span class="line"></span><br><span class="line">    //构造分页构造器</span><br><span class="line">    Page pageInfo = new Page(page,pageSize);</span><br><span class="line"></span><br><span class="line">    //构造条件构造器</span><br><span class="line">    LambdaQueryWrapper&lt;Employee&gt; queryWrapper = new LambdaQueryWrapper();</span><br><span class="line">    //添加一个过滤条件</span><br><span class="line">    queryWrapper.like(!StringUtils.isEmpty(name),Employee::getName,name);</span><br><span class="line">    //添加排序条件</span><br><span class="line">    queryWrapper.orderByDesc(Employee::getUpdateTime);</span><br><span class="line"></span><br><span class="line">    //执行查询</span><br><span class="line">    employeeService.page(pageInfo,queryWrapper);</span><br><span class="line"></span><br><span class="line">    return R.success(pageInfo);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="员工账号状态功能实现"><a href="#员工账号状态功能实现" class="headerlink" title="员工账号状态功能实现"></a>员工账号状态功能实现</h3><p>根据启用&#x2F;禁用按钮得知，需要在employee下通过id来改变status状态。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"> /**</span><br><span class="line"> * 根据id修改员工信息</span><br><span class="line"> * @param employee</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line">@PutMapping</span><br><span class="line">public R&lt;String&gt; update(HttpServletRequest request, @RequestBody Employee employee)&#123;</span><br><span class="line">    log.info(employee.toString());</span><br><span class="line"></span><br><span class="line">    Long empId = (Long) request.getSession().getAttribute(&quot;employee&quot;);</span><br><span class="line">    employee.setUpdateTime(LocalDateTime.now());</span><br><span class="line">    employee.setUpdateUser(empId);</span><br><span class="line"></span><br><span class="line">    employeeService.updateById(employee);</span><br><span class="line"></span><br><span class="line">    return R.success(&quot;员工信息修改成功&quot;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>此时出现bug不能实现，原因： html页面在处理较长的整数字段时会影响数据精度，造成数据丢失，导致后台和前台的id不一致</p>
<p>解决办法：将long型的数字类型转为json字符串类型，需要引入一个对象映射器JacksonObjectMapper 放到common下</p>
<p>在config&#x2F;WebMvcConfig下来扩展mvc框架的消息转化器</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> /**</span><br><span class="line"> * 扩展mvc框架的消息转换器</span><br><span class="line"> * @param converters</span><br><span class="line"> */</span><br><span class="line">@Override</span><br><span class="line">protected void extendMessageConverters(List&lt;HttpMessageConverter&lt;?&gt;&gt; converters) &#123;</span><br><span class="line">    log.info(&quot;扩展消息转换器...&quot;);</span><br><span class="line">    //创建消息转换器对象</span><br><span class="line">    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();</span><br><span class="line">    //设置对象转换器，底层使用Jackson将Java对象转为json</span><br><span class="line">    messageConverter.setObjectMapper(new JacksonObjectMapper());</span><br><span class="line">    //将上面的消息转换器对象追加到mvc框架的转换器集合中</span><br><span class="line">    converters.add(0,messageConverter);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="编辑员工信息功能实现"><a href="#编辑员工信息功能实现" class="headerlink" title="编辑员工信息功能实现"></a>编辑员工信息功能实现</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> /**</span><br><span class="line"> * 根据id查询员工信息</span><br><span class="line"> * @param id</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line">@GetMapping(&quot;/&#123;id&#125;&quot;)</span><br><span class="line">public R&lt;Employee&gt; getById(@PathVariable Long id) &#123;</span><br><span class="line">    log.info(&quot;根据id查询员工信息...&quot;);</span><br><span class="line">    Employee employee = employeeService.getById(id);</span><br><span class="line">    if (employee != null) &#123;</span><br><span class="line">        return R.success(employee);</span><br><span class="line">    &#125;</span><br><span class="line">    return R.error(&quot;没有查询到对应员工信息&quot;);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="公共字段自动填充功能的实现"><a href="#公共字段自动填充功能的实现" class="headerlink" title="公共字段自动填充功能的实现"></a>公共字段自动填充功能的实现</h3><p>1.在entity里边的Employee中添加两个注解为要实现公共填充的字段<br><code>@TableField(fill = FieldFill.INSERT)</code><br><code>@TableField(fill = FieldFill.INSERT_UPDATE)</code></p>
<p>2.在common下创建一个类MetaObjectHandler</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">package com.yiyi.reggie.commmon;</span><br><span class="line"></span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.apache.ibatis.reflection.MetaObject;</span><br><span class="line">import org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line">import java.time.LocalDateTime;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 自定义元数据对象处理器</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line">@Component</span><br><span class="line">@Slf4j</span><br><span class="line">public class MetaObjectHandler implements com.baomidou.mybatisplus.core.handlers.MetaObjectHandler &#123;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 插入操作，自动填充</span><br><span class="line">     * @param metaObject</span><br><span class="line">     */</span><br><span class="line">    @Override</span><br><span class="line">    public void insertFill(MetaObject metaObject) &#123;</span><br><span class="line">        log.info(&quot;公共字段自动填充[insert]...&quot;);</span><br><span class="line">        log.info(metaObject.toString());</span><br><span class="line">        metaObject.setValue(&quot;createTime&quot;, LocalDateTime.now());</span><br><span class="line">        metaObject.setValue(&quot;updateTime&quot;, LocalDateTime.now());</span><br><span class="line">        metaObject.setValue(&quot;createUser&quot;, BaseContext.getCurrentId());</span><br><span class="line">        metaObject.setValue(&quot;updateUser&quot;, BaseContext.getCurrentId());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public void updateFill(MetaObject metaObject) &#123;</span><br><span class="line">        log.info(&quot;公共字段自动填充[update]...&quot;);</span><br><span class="line">        log.info(metaObject.toString());</span><br><span class="line"></span><br><span class="line">        long id = Thread.currentThread().getId();</span><br><span class="line">        log.info(&quot;线程id为: &#123;&#125;&quot;,id);</span><br><span class="line"></span><br><span class="line">        metaObject.setValue(&quot;updateTime&quot;, LocalDateTime.now());</span><br><span class="line">        metaObject.setValue(&quot;updateUser&quot;, BaseContext.getCurrentId());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>3.在common下创建一个线程封装工具BaseContext</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">package com.yiyi.reggie.commmon;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 基于ThreadLocal封装工具类，用户保存和获取当前登录用户id</span><br><span class="line"> */</span><br><span class="line">public class BaseContext &#123;</span><br><span class="line">    private static ThreadLocal&lt;Long&gt; threadLocal = new ThreadLocal&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 设置值</span><br><span class="line">     * @param id</span><br><span class="line">     */</span><br><span class="line">    public static void setCurrentId(Long id)&#123;</span><br><span class="line">        threadLocal.set(id);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 获取值</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    public static Long getCurrentId()&#123;</span><br><span class="line">        return threadLocal.get();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>4.将EmployeeController中的增加和修改的代码部分删除或注释</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">    /**</span><br><span class="line">     * 根据id修改员工信息</span><br><span class="line">     * @param employee</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PutMapping</span><br><span class="line">    public R&lt;String&gt; update(HttpServletRequest request, @RequestBody Employee employee)&#123;</span><br><span class="line">        log.info(employee.toString());</span><br><span class="line"></span><br><span class="line">        long id = Thread.currentThread().getId();</span><br><span class="line">        log.info(&quot;线程id为：&#123;&#125;&quot;,id);</span><br><span class="line">//        Long empId = (Long) request.getSession().getAttribute(&quot;employee&quot;);</span><br><span class="line">//        employee.setUpdateTime(LocalDateTime.now());</span><br><span class="line">//        employee.setUpdateUser(empId);</span><br><span class="line"></span><br><span class="line">        employeeService.updateById(employee);</span><br><span class="line"></span><br><span class="line">        return R.success(&quot;员工信息修改成功&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">    /**</span><br><span class="line">     * 新增员工</span><br><span class="line">     * @param employee</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping</span><br><span class="line">    public R&lt;String&gt; save(HttpServletRequest request, @RequestBody Employee employee)&#123;</span><br><span class="line">        log.info(&quot;新增员工，员工信息：&#123;&#125;&quot;,employee.toString());</span><br><span class="line"></span><br><span class="line">        //设置初始密码123456，需要进行md5加密处理</span><br><span class="line">        employee.setPassword(DigestUtils.md5DigestAsHex(&quot;123456&quot;.getBytes()));</span><br><span class="line"></span><br><span class="line">//        employee.setCreateTime(LocalDateTime.now());</span><br><span class="line">//        employee.setUpdateTime(LocalDateTime.now());</span><br><span class="line">//</span><br><span class="line">//        //获得当前登录用户的id</span><br><span class="line">//        Long empId = (Long) request.getSession().getAttribute(&quot;employee&quot;);</span><br><span class="line">//</span><br><span class="line">//        employee.setCreateUser(empId);</span><br><span class="line">//        employee.setUpdateUser(empId);</span><br><span class="line"></span><br><span class="line">        employeeService.save(employee);</span><br><span class="line">        return R.success(&quot;新增员工成功&quot;);</span><br></pre></td></tr></table></figure>

<p>##分类管理</p>
<h3 id="新增分类功能实现-Category-页面"><a href="#新增分类功能实现-Category-页面" class="headerlink" title="新增分类功能实现(Category 页面)"></a>新增分类功能实现(Category 页面)</h3><p>导入Category实体类，mapper，service，serviceImpl，创建按CategoryController</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 新增分类</span><br><span class="line">     * @param category</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping</span><br><span class="line">    public R&lt;String&gt; save(@RequestBody Category category)&#123;</span><br><span class="line">        log.info(&quot;category: &#123;&#125;&quot;,category);</span><br><span class="line"></span><br><span class="line">        categoryService.save(category);</span><br><span class="line">        return R.success(&quot;新增分类成功&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h3 id="分页查询功能实现"><a href="#分页查询功能实现" class="headerlink" title="分页查询功能实现"></a>分页查询功能实现</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 分页查查询</span><br><span class="line">     * @param page</span><br><span class="line">     * @param pageSize</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @GetMapping(&quot;/page&quot;)</span><br><span class="line">    public R&lt;Page&gt; page(int page,int pageSize)&#123;</span><br><span class="line">        //分页构造器</span><br><span class="line">        Page&lt;Category&gt; pageInfo = new Page&lt;&gt;(page,pageSize);</span><br><span class="line">        //条件构造器</span><br><span class="line">        LambdaQueryWrapper&lt;Category&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        //添加排序条件，根据sort进行排序</span><br><span class="line">        queryWrapper.orderByAsc(Category::getSort);</span><br><span class="line"></span><br><span class="line">        //进行分页查询</span><br><span class="line">        categoryService.page(pageInfo,queryWrapper);</span><br><span class="line">        return R.success(pageInfo);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="删除分类功能实现"><a href="#删除分类功能实现" class="headerlink" title="删除分类功能实现"></a>删除分类功能实现</h3><p>分析：有关联数据的删除，自定义remove方法，在CategoryService中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">public void remove(Long id);</span><br></pre></td></tr></table></figure>

<p>在CategoryServiceImpl中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">@Autowired</span><br><span class="line">    private DishService dishService;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private SetmealService setmealService;</span><br><span class="line">    /**</span><br><span class="line">     * 根据id删除分类，删除之前需要进行判断</span><br><span class="line">     * @param id</span><br><span class="line">     */</span><br><span class="line">    @Override</span><br><span class="line">    public void remove(Long id) &#123;</span><br><span class="line">        LambdaQueryWrapper&lt;Dish&gt; dishLambdaQueryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        //添加查询条件，根据分类id进行查询</span><br><span class="line">        dishLambdaQueryWrapper.eq(Dish::getCategoryId,id);</span><br><span class="line"></span><br><span class="line">        int count1 = dishService.count(dishLambdaQueryWrapper);</span><br><span class="line"></span><br><span class="line">        //查询当前分类是否关联了菜品，如果已经关联，抛出一个业务异常</span><br><span class="line">        if (count1 &gt; 0) &#123;</span><br><span class="line">            //已经关联,抛出一个异常</span><br><span class="line">            throw new CustomException(&quot;当前分类下关联了菜品，不能删除&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        LambdaQueryWrapper&lt;Setmeal&gt; setmealLambdaQueryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        //添加查询条件，根据分类id进行查询</span><br><span class="line">        setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId,id);</span><br><span class="line"></span><br><span class="line">        int count2 =setmealService.count(setmealLambdaQueryWrapper);</span><br><span class="line">        //查询当前分类是否关联了套餐，如果已经关联，抛出一个业务异常</span><br><span class="line">        if (count2 &gt;0)&#123;</span><br><span class="line">            //已经关联，抛出异常</span><br><span class="line">            throw new CustomException(&quot;当前分类下关联了菜单，不能删除&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        //正常删除</span><br><span class="line">        super.removeById(id);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>抛出的异常已经不属于全局的异常，所以我们还需要再自定义一个异常处理器CustomException</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"> * 自定义业务处理器</span><br><span class="line"> */</span><br><span class="line">public class CustomException extends RuntimeException&#123;</span><br><span class="line"></span><br><span class="line">    public CustomException(String message)&#123;</span><br><span class="line">        super(message);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>同时需要再全局自定义处理器中，自定义处理方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 异常处理方法</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @ExceptionHandler(CustomException.class)</span><br><span class="line">    public R&lt;String&gt; customHandler(CustomException ex)&#123;</span><br><span class="line">        log.error(ex.getMessage());</span><br><span class="line"></span><br><span class="line">        return R.error(ex.getMessage());</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="修改分类功能实现"><a href="#修改分类功能实现" class="headerlink" title="修改分类功能实现"></a>修改分类功能实现</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 根据id修改分类信息</span><br><span class="line">     * @param category</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PutMapping</span><br><span class="line">    public R&lt;String&gt; update(@RequestBody Category category)&#123;</span><br><span class="line">        log.info(&quot;修改分类信息&quot;);</span><br><span class="line"></span><br><span class="line">        categoryService.updateById(category);</span><br><span class="line"></span><br><span class="line">        return R.success(&quot;修改成功&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h2 id="菜品管理"><a href="#菜品管理" class="headerlink" title="菜品管理"></a>菜品管理</h2><h3 id="文件的上传与下载"><a href="#文件的上传与下载" class="headerlink" title="文件的上传与下载"></a>文件的上传与下载</h3><p>创建一个commonController，在application.yml中配置basePath</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">reggie:</span><br><span class="line">  path: D:\</span><br></pre></td></tr></table></figure>


<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br></pre></td><td class="code"><pre><span class="line">package com.yiyi.reggie.controller;</span><br><span class="line"></span><br><span class="line">import com.yiyi.reggie.commmon.R;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Value;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PostMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.RequestMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line">import org.springframework.web.multipart.MultipartFile;</span><br><span class="line"></span><br><span class="line">import javax.servlet.ServletOutputStream;</span><br><span class="line">import javax.servlet.http.HttpServletResponse;</span><br><span class="line">import java.io.File;</span><br><span class="line">import java.io.FileInputStream;</span><br><span class="line">import java.io.FileNotFoundException;</span><br><span class="line">import java.io.IOException;</span><br><span class="line">import java.util.UUID;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * 文件的上传与下载</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@RequestMapping(&quot;/common&quot;)</span><br><span class="line">@Slf4j</span><br><span class="line">public class CommonController &#123;</span><br><span class="line"></span><br><span class="line">    @Value(&quot;$&#123;reggie.path&#125;&quot;)</span><br><span class="line">    private String basePath;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 文件上传</span><br><span class="line">     * @param file</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping(&quot;/upload&quot;)</span><br><span class="line">    public R&lt;String&gt; upload(MultipartFile file)&#123;</span><br><span class="line">        //file是一个临时文件，需要转存到指定位置，否则本次请求完成后临时文件会删除</span><br><span class="line">        log.info(file.toString());</span><br><span class="line"></span><br><span class="line">        //原始文件名</span><br><span class="line">        String originalFilename =  file.getOriginalFilename();</span><br><span class="line">        String suffix = originalFilename.substring(originalFilename.lastIndexOf(&quot;.&quot;));</span><br><span class="line"></span><br><span class="line">        //使用UUID重现生成文件名，防止文件名称重复造成文件覆盖</span><br><span class="line">        String fileName = UUID.randomUUID().toString()+suffix;</span><br><span class="line"></span><br><span class="line">        //创建一个目录对象</span><br><span class="line">        File dir = new File(basePath);</span><br><span class="line">        //判断当前目录是否存在</span><br><span class="line">        if (!dir.exists())&#123;</span><br><span class="line">            //目录不存在，需要创建</span><br><span class="line">            dir.mkdirs();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        try &#123;</span><br><span class="line">            file.transferTo(new File(basePath + fileName));</span><br><span class="line">        &#125; catch (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        return R.success(fileName);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 文件下载</span><br><span class="line">     * @param name</span><br><span class="line">     * @param response</span><br><span class="line">     */</span><br><span class="line">    @GetMapping(&quot;/download&quot;)</span><br><span class="line">    public void download(String name, HttpServletResponse response)&#123;</span><br><span class="line">        //输入流，通过输入流读取文件内容</span><br><span class="line">        try &#123;</span><br><span class="line">            FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));</span><br><span class="line"></span><br><span class="line">            //输出流，通过输出流将文件写回到浏览器中，在浏览器展示图片</span><br><span class="line">            ServletOutputStream outputStream = response.getOutputStream();</span><br><span class="line"></span><br><span class="line">            response.setContentType(&quot;image/jpeg&quot;);</span><br><span class="line"></span><br><span class="line">            int len = 0;</span><br><span class="line">            byte[] bytes = new byte[1024];</span><br><span class="line">            while ( ( len = fileInputStream.read(bytes)) != -1)&#123;</span><br><span class="line">                outputStream.write(bytes,0,len);</span><br><span class="line">                outputStream.flush();</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            //关闭电源</span><br><span class="line">            outputStream.close();</span><br><span class="line">            fileInputStream.close();</span><br><span class="line">        &#125; catch (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="菜品管理-1"><a href="#菜品管理-1" class="headerlink" title="菜品管理"></a>菜品管理</h2><h3 id="需求分析"><a href="#需求分析" class="headerlink" title="需求分析"></a>需求分析</h3><p>两个表 1. dish 菜品表 2.dish_flavor 菜品口味表<br>实现业务功能前，先将需要用到的类和接口基本结构创建好：<br>*实体类 DishFlavor Dish<br>*Mapper 接口 DishFlaverMapper<br>业务层接口 DishFlavorService<br>业务层实现类 DishFlavorServiceImpl<br>控制层 DishController</p>
<h3 id="新增菜品"><a href="#新增菜品" class="headerlink" title="新增菜品"></a>新增菜品</h3><p>1.新增菜品的菜品分类复现选择</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">   * 根据条件查询分了类数据</span><br><span class="line">   * @param category</span><br><span class="line">   * @return</span><br><span class="line">   */</span><br><span class="line">  @GetMapping(&quot;/list&quot;)</span><br><span class="line">  public R&lt;List&lt;Category&gt;&gt; list(Category category)&#123;</span><br><span class="line">      //条件构造器</span><br><span class="line">      LambdaQueryWrapper&lt;Category&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">      //添加条件</span><br><span class="line">      queryWrapper.eq(category.getType() != null,Category::getType,category.getType());</span><br><span class="line">      //添加排序条件</span><br><span class="line">      queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);</span><br><span class="line"></span><br><span class="line">      List&lt;Category&gt; list = categoryService.list(queryWrapper);</span><br><span class="line">      return R.success(list);</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure>

<p>2.实现新增菜品的提交保存<br>**由于前端请求的数据比较复杂，且Dish实体类不能全部包括 所以我们引入DTO，全称为Data Transfer Object，即数据传输对象，一般用于展示层与服务层之间的数据传输</p>
<p>我们在service中自定义一个方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line">package com.yiyi.reggie.service.impl;</span><br><span class="line"></span><br><span class="line">import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;</span><br><span class="line">import com.yiyi.reggie.dto.DishDto;</span><br><span class="line">import com.yiyi.reggie.entity.Dish;</span><br><span class="line">import com.yiyi.reggie.entity.DishFlavor;</span><br><span class="line">import com.yiyi.reggie.mapper.DishMapper;</span><br><span class="line">import com.yiyi.reggie.service.DishFlavorService;</span><br><span class="line">import com.yiyi.reggie.service.DishService;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.stereotype.Service;</span><br><span class="line">import org.springframework.transaction.annotation.Transactional;</span><br><span class="line"></span><br><span class="line">import java.util.List;</span><br><span class="line">import java.util.stream.Collectors;</span><br><span class="line"></span><br><span class="line">@Service</span><br><span class="line">@Slf4j</span><br><span class="line">public class DishServiceImpl extends ServiceImpl&lt;DishMapper, Dish&gt; implements DishService &#123;</span><br><span class="line"></span><br><span class="line">    @Autowired</span><br><span class="line">    private DishFlavorService dishFlavorService;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 新增菜品，同时保存对应的口味数据</span><br><span class="line">     * @param dishDto</span><br><span class="line">     */</span><br><span class="line">    @Transactional</span><br><span class="line">    public void saveWithFlavor(DishDto dishDto) &#123;</span><br><span class="line">        //保存菜品的基本信息到菜品表dish</span><br><span class="line">        this.save(dishDto);</span><br><span class="line"></span><br><span class="line">        Long dishId = dishDto.getId();//菜品id</span><br><span class="line"></span><br><span class="line">        //菜品口味</span><br><span class="line">        List&lt;DishFlavor&gt; flavors = dishDto.getFlavors();</span><br><span class="line">        flavors = flavors.stream().map((item) -&gt; &#123;</span><br><span class="line">            item.setDishId(dishId);</span><br><span class="line">            return item;</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line">        //保存菜品口味数据到菜品口味表dish_flavor</span><br><span class="line">        dishFlavorService.saveBatch(flavors );</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>然后再controller中实现</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 新增菜品</span><br><span class="line">     * @param dishDto</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping</span><br><span class="line">    public R&lt;String&gt; save(@RequestBody DishDto dishDto)&#123;</span><br><span class="line">        log.info(dishDto.toString());</span><br><span class="line"></span><br><span class="line">        dishService.saveWithFlavor(dishDto);</span><br><span class="line">        return R.success(&quot;新增菜品成功&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="菜品信息分页查询"><a href="#菜品信息分页查询" class="headerlink" title="菜品信息分页查询"></a>菜品信息分页查询</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 菜品信息分页查询</span><br><span class="line">     * @param page</span><br><span class="line">     * @param pageSize</span><br><span class="line">     * @param name</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @GetMapping(&quot;/page&quot;)</span><br><span class="line">    public R&lt;Page&gt; page(int page,int pageSize,String name)&#123;</span><br><span class="line"></span><br><span class="line">        //构造分页器对象</span><br><span class="line">        Page&lt;Dish&gt; pageInfo = new Page&lt;&gt;(page,pageSize);</span><br><span class="line">        Page&lt;DishDto&gt; dishDtoPage = new Page&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        //构造条件构造器</span><br><span class="line">        LambdaQueryWrapper&lt;Dish&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        //添加过滤条件</span><br><span class="line">        queryWrapper.like(name!=null,Dish::getName,name);</span><br><span class="line"></span><br><span class="line">        //添加排序条件</span><br><span class="line">        queryWrapper.orderByDesc(Dish::getUpdateTime);</span><br><span class="line"></span><br><span class="line">        //执行分页查询</span><br><span class="line">        dishService.page(pageInfo,queryWrapper);</span><br><span class="line"></span><br><span class="line">        //对象拷贝</span><br><span class="line">        BeanUtils.copyProperties(pageInfo,dishDtoPage,&quot;records&quot;);</span><br><span class="line"></span><br><span class="line">        List&lt;Dish&gt; records = pageInfo.getRecords();</span><br><span class="line">        List&lt;DishDto&gt; list = records.stream().map((item) -&gt; &#123;</span><br><span class="line">            DishDto dishDto = new DishDto();</span><br><span class="line"></span><br><span class="line">            BeanUtils.copyProperties(item,dishDto);</span><br><span class="line"></span><br><span class="line">            Long categoryId = item.getCategoryId();</span><br><span class="line">            //根据id查询分类对象</span><br><span class="line">            Category category = categoryService.getById(categoryId);</span><br><span class="line"></span><br><span class="line">            if (category !=null )&#123;</span><br><span class="line">                String categoryName = category.getName();</span><br><span class="line">                dishDto.setCategoryName(categoryName);</span><br><span class="line">            &#125;</span><br><span class="line">            return dishDto;</span><br><span class="line">            </span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line">        dishDtoPage.setRecords(list);</span><br><span class="line"></span><br><span class="line">        return R.success(dishDtoPage);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="编辑菜品信息"><a href="#编辑菜品信息" class="headerlink" title="编辑菜品信息"></a>编辑菜品信息</h3><p>1.首先自定义一个方法，为了显示菜品信息和相关口味两个信息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 根据id查询菜品信息和相关口味信息</span><br><span class="line">     * @param id</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @Override</span><br><span class="line">    public DishDto getByIdWithFlavor(Long id) &#123;</span><br><span class="line">        //查询菜品基本信息，从dish表查询</span><br><span class="line">        Dish dish = this.getById(id);</span><br><span class="line"></span><br><span class="line">        DishDto dishDto = new DishDto();</span><br><span class="line">        BeanUtils.copyProperties(dish,dishDto);</span><br><span class="line"></span><br><span class="line">        //查询当前菜品对应的口味信息，从dish_flavor表查询</span><br><span class="line">        LambdaQueryWrapper&lt;DishFlavor&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        queryWrapper.eq(DishFlavor::getDishId,dish.getId());</span><br><span class="line">        List&lt;DishFlavor&gt; flavors = dishFlavorService.list(queryWrapper);</span><br><span class="line">        dishDto.setFlavors(flavors);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        return dishDto;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>然后就在controller中实现就ok了</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 根据id查询菜品信息和相关口味信息</span><br><span class="line">     * @param id</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @GetMapping(&quot;/&#123;id&#125;&quot;)</span><br><span class="line">    public R&lt;DishDto&gt; get(@PathVariable Long id)&#123;</span><br><span class="line"></span><br><span class="line">        DishDto dishDto = dishService.getByIdWithFlavor(id);</span><br><span class="line"></span><br><span class="line">        return R.success(dishDto);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>2.实现修改后提交功能<br>自定义一个方法update</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 更新菜品信息，同时更新口味信息</span><br><span class="line">     * @param dishDto</span><br><span class="line">     */</span><br><span class="line">    @Override</span><br><span class="line">    @Transactional</span><br><span class="line">    public void updateWithFlavor(DishDto dishDto) &#123;</span><br><span class="line">        //更新dish表基本信息</span><br><span class="line">        this.updateById(dishDto);</span><br><span class="line"></span><br><span class="line">        //清理当前菜品对应口味数据---dish_flavor表的delete操作</span><br><span class="line">        LambdaQueryWrapper&lt;DishFlavor&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());</span><br><span class="line"></span><br><span class="line">        dishFlavorService.remove(queryWrapper);</span><br><span class="line">        //添加当前提交过来的口味数据---dish_flavor表的insert操作</span><br><span class="line">        List&lt;DishFlavor&gt; flavors = dishDto.getFlavors();</span><br><span class="line"></span><br><span class="line">        flavors = flavors.stream().map((item) -&gt; &#123;</span><br><span class="line">            item.setDishId(dishDto.getId());</span><br><span class="line">            return item;</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        //保存菜品口味数据到菜品口味表---dish_flavor</span><br><span class="line">        dishFlavorService.saveBatch(flavors);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>在controller中实现一下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 更新菜品信息，同时更新口味信息</span><br><span class="line">     * @param dishDto</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PutMapping</span><br><span class="line">    public R&lt;String&gt; update(@RequestBody DishDto dishDto)&#123;</span><br><span class="line">        log.info(dishDto.toString());</span><br><span class="line"></span><br><span class="line">        dishService.updateWithFlavor(dishDto);</span><br><span class="line"></span><br><span class="line">        return R.success(&quot;修改菜品成功&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h2 id="套餐管理功能的实现"><a href="#套餐管理功能的实现" class="headerlink" title="套餐管理功能的实现"></a>套餐管理功能的实现</h2><h3 id="添加套餐菜品的选择复选"><a href="#添加套餐菜品的选择复选" class="headerlink" title="添加套餐菜品的选择复选"></a>添加套餐菜品的选择复选</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     *  添加套餐菜品</span><br><span class="line">     * @param dish</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @GetMapping(&quot;/list&quot;)</span><br><span class="line">    public R&lt;List&lt;Dish&gt;&gt; list(Dish dish)&#123;</span><br><span class="line"></span><br><span class="line">        //构造查询条件</span><br><span class="line">        LambdaQueryWrapper&lt;Dish&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        queryWrapper.eq(dish.getCategoryId() != null,Dish::getCategoryId,dish.getCategoryId());</span><br><span class="line">        //添加条件，查询状态为1的</span><br><span class="line">        queryWrapper.eq(Dish::getStatus,1);</span><br><span class="line">        //添加排序条件</span><br><span class="line">        queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);</span><br><span class="line"></span><br><span class="line">        List&lt;Dish&gt; list = dishService.list(queryWrapper);</span><br><span class="line"></span><br><span class="line">        return R.success(list);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="添加套餐菜品的功能实现"><a href="#添加套餐菜品的功能实现" class="headerlink" title="添加套餐菜品的功能实现"></a>添加套餐菜品的功能实现</h3><p>需要用到dto将setmeal和setmealDish的字段合并<br>SetmealDishServiceImpl中实现方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">@Autowired</span><br><span class="line">    private SetmealDishService setmealDishService;</span><br><span class="line"></span><br><span class="line">    /**</span><br><span class="line">     * 新增套餐，同时需要保存套餐和菜品的关系</span><br><span class="line">     * @param setmealDto</span><br><span class="line">     */</span><br><span class="line">    @Transactional</span><br><span class="line">    public void saveWithDish(SetmealDto setmealDto) &#123;</span><br><span class="line">        //保存套餐的基本信息，操作setmeal，执行insert操作</span><br><span class="line">        this.save(setmealDto);</span><br><span class="line"></span><br><span class="line">        List&lt;SetmealDish&gt; setmealDishes = setmealDto.getSetmealDishes();</span><br><span class="line">        setmealDishes.stream().map((item)-&gt;&#123;</span><br><span class="line">            item.setSetmealId(setmealDto.getId());</span><br><span class="line">            return item;</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line">        //保存套餐和菜品的关联信息，操作setmeal，执行insert操作</span><br><span class="line">        setmealDishService.saveBatch(setmealDishes);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>在controller中实现控制</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 新增套餐</span><br><span class="line">     * @param setmealDto</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping</span><br><span class="line">    public R&lt;String&gt; save(@RequestBody SetmealDto setmealDto)&#123;</span><br><span class="line">        log.info(&quot;套餐信息：&#123;&#125;&quot;,setmealDto);</span><br><span class="line"></span><br><span class="line">        setmealService.saveWithDish(setmealDto);</span><br><span class="line"></span><br><span class="line">        return R.success(&quot;新增套餐成功&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="套餐管理页面的显示功能实现list"><a href="#套餐管理页面的显示功能实现list" class="headerlink" title="套餐管理页面的显示功能实现list"></a>套餐管理页面的显示功能实现list</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line">    @Autowired</span><br><span class="line">    private CategoryService categoryService;</span><br><span class="line">    </span><br><span class="line">/**</span><br><span class="line">     * 套餐分页查询</span><br><span class="line">     * @param page</span><br><span class="line">     * @param pageSize</span><br><span class="line">     * @param name</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @GetMapping(&quot;/page&quot;)</span><br><span class="line">    public R&lt;Page&gt; page(int page,int pageSize,String name)&#123;</span><br><span class="line">        log.info(&quot;&quot;);</span><br><span class="line">        //分页构造器对象</span><br><span class="line">        Page&lt;Setmeal&gt; pageInfo = new Page&lt;&gt;(page,pageSize);</span><br><span class="line">        Page&lt;SetmealDto&gt; pageDto = new Page&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        LambdaQueryWrapper&lt;Setmeal&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line"></span><br><span class="line">        //添加查询条件，根据name进行like模糊查询</span><br><span class="line">        queryWrapper.like(name != null,Setmeal::getName,name);</span><br><span class="line">        //添加排序条件，根据更新时间降序排列</span><br><span class="line">        queryWrapper.orderByDesc(Setmeal::getUpdateTime);</span><br><span class="line"></span><br><span class="line">        setmealService.page(pageInfo,queryWrapper);</span><br><span class="line"></span><br><span class="line">        //对象的拷贝</span><br><span class="line">        BeanUtils.copyProperties(pageInfo,pageDto,&quot;records&quot;);</span><br><span class="line">        List&lt;Setmeal&gt; records = pageInfo.getRecords();</span><br><span class="line"></span><br><span class="line">        List&lt;SetmealDto&gt; list = records.stream().map((item)-&gt;&#123;</span><br><span class="line">            SetmealDto setmealDto = new SetmealDto();</span><br><span class="line">            //对象拷贝</span><br><span class="line">            BeanUtils.copyProperties(item,setmealDto);</span><br><span class="line">            //分类id</span><br><span class="line">            Long categoryId = item.getCategoryId();</span><br><span class="line">            //根据分类id查询分类对象</span><br><span class="line">            Category category = categoryService.getById(categoryId);</span><br><span class="line">            if(category != null)&#123;</span><br><span class="line">                //分类名称</span><br><span class="line">                String categoryName = category.getName();</span><br><span class="line">                setmealDto.setCategoryName(categoryName);</span><br><span class="line">            &#125;</span><br><span class="line">            return setmealDto;</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line">        pageDto.setRecords(list);</span><br><span class="line">        return R.success(pageDto);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="删除套餐管理功能实现"><a href="#删除套餐管理功能实现" class="headerlink" title="删除套餐管理功能实现"></a>删除套餐管理功能实现</h3><p>自定义一个 removeWithDish 方法 在setmealServiceImpl中</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 删除套餐，同时删除相关菜品信息</span><br><span class="line">     * @param ids</span><br><span class="line">     */</span><br><span class="line">    @Transactional</span><br><span class="line">    public void removeWithDish(List&lt;Long&gt; ids) &#123;</span><br><span class="line">        //查询套餐状态，确定是否可以山粗</span><br><span class="line">        LambdaQueryWrapper&lt;Setmeal&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        queryWrapper.in(Setmeal::getId,ids);</span><br><span class="line">        queryWrapper.eq(Setmeal::getStatus,1);</span><br><span class="line"></span><br><span class="line">        int count = this.count(queryWrapper);</span><br><span class="line">        if (count &gt; 0)&#123;</span><br><span class="line">            //如果不可以删除，抛出一个业务异常</span><br><span class="line">            throw new CustomException(&quot;套餐正在售卖中，不能删除&quot;);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        //如果可以删除，先删除套餐表中的数据---setmeal</span><br><span class="line">        this.removeByIds(ids);</span><br><span class="line"></span><br><span class="line">        LambdaQueryWrapper&lt;SetmealDish&gt; queryWrapper1 = new LambdaQueryWrapper&lt;&gt;();</span><br><span class="line">        queryWrapper1.in(SetmealDish::getSetmealId,ids);</span><br><span class="line"></span><br><span class="line">        //删除关系表中的数据 --- setmealDish</span><br><span class="line">        setmealDishService.remove(queryWrapper1);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>在setmealController中，引用 removeWithDish 将ids传入即可实现</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 删除套餐</span><br><span class="line">     * @param ids</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @DeleteMapping</span><br><span class="line">    public R&lt;String&gt; delete(@RequestParam List&lt;Long&gt; ids)&#123;</span><br><span class="line">        log.info(&quot;ids:&#123;&#125;&quot;,ids);</span><br><span class="line"></span><br><span class="line">        setmealService.removeWithDish(ids);</span><br><span class="line">        return R.success(&quot;套餐数据删除成功&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h2 id="短信发送"><a href="#短信发送" class="headerlink" title="短信发送"></a>短信发送</h2><h3 id="引入框架-Mapper-Service-ServiceImpl-Controller-（User）"><a href="#引入框架-Mapper-Service-ServiceImpl-Controller-（User）" class="headerlink" title="引入框架 Mapper Service ServiceImpl Controller （User）"></a>引入框架 Mapper Service ServiceImpl Controller （User）</h3><h3 id="改进用户端的登陆状态（与管理端类似）"><a href="#改进用户端的登陆状态（与管理端类似）" class="headerlink" title="改进用户端的登陆状态（与管理端类似）"></a>改进用户端的登陆状态（与管理端类似）</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">// 4.2判断登录状态，如已登录，则直接放行</span><br><span class="line">        if(request.getSession().getAttribute(&quot;user&quot;) != null)&#123;</span><br><span class="line">            log.info(&quot;用户已登录,用户id为:&#123;&#125;&quot;,request.getSession().getAttribute(&quot;user&quot;));</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">            Long userId = (Long) request.getSession().getAttribute(&quot;user&quot;);</span><br><span class="line">            BaseContext.setCurrentId(userId);</span><br><span class="line"></span><br><span class="line">            filterChain.doFilter(request,response);</span><br><span class="line">            return;</span><br><span class="line">        &#125;</span><br></pre></td></tr></table></figure>

<h3 id="短信发送验证码功能实现"><a href="#短信发送验证码功能实现" class="headerlink" title="短信发送验证码功能实现"></a>短信发送验证码功能实现</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 短信发送验证码</span><br><span class="line">     * @param user</span><br><span class="line">     * @param session</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping(&quot;/sendMsg&quot;)</span><br><span class="line">    public R&lt;String&gt; sendMsg(@RequestBody User user, HttpSession session)&#123;</span><br><span class="line">        //获取手机号</span><br><span class="line">        String phone = user.getPhone();</span><br><span class="line"></span><br><span class="line">        if (!StringUtils.isEmpty(phone))&#123;</span><br><span class="line">            //生成随机的4位验证码</span><br><span class="line">            String code = ValidateCodeUtils.generateValidateCode(4).toString();</span><br><span class="line">            log.info(&quot;code=&#123;&#125;&quot;,code);</span><br><span class="line"></span><br><span class="line">            //调用阿里云提供的短信服务API完成发送短信</span><br><span class="line">            //SMSUtils.sendMessage(&quot;吉瑞外卖&quot;,&quot;&quot;,phone,code);</span><br><span class="line"></span><br><span class="line">            //需要将生成的验证码保存到Session</span><br><span class="line">            session.setAttribute(phone,code);</span><br><span class="line"></span><br><span class="line">            return R.success(&quot;手机验证码短信发送成功&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        return R.error(&quot;短信发送失败&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h3 id="验证码填写完成登录功能的实现"><a href="#验证码填写完成登录功能的实现" class="headerlink" title="验证码填写完成登录功能的实现"></a>验证码填写完成登录功能的实现</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * 移动端用户登录</span><br><span class="line">     * @param map</span><br><span class="line">     * @param session</span><br><span class="line">     * @return</span><br><span class="line">     */</span><br><span class="line">    @PostMapping(&quot;/login&quot;)</span><br><span class="line">    public R&lt;User&gt; login(@RequestBody Map map,HttpSession session)&#123;</span><br><span class="line">        log.info(map.toString());</span><br><span class="line"></span><br><span class="line">        //获取手机号</span><br><span class="line">        String phone = map.get(&quot;phone&quot;).toString();</span><br><span class="line">        //获取验证码</span><br><span class="line">        String code = map.get(&quot;code&quot;).toString();</span><br><span class="line"></span><br><span class="line">        //从Session中获取保存的验证码</span><br><span class="line">        Object codeInSession = session.getAttribute(phone);</span><br><span class="line"></span><br><span class="line">        //进行验证码的对比（页面提交的验证码和Session中保存的验证码比对）</span><br><span class="line">        if (codeInSession != null &amp;&amp; codeInSession.equals(code))&#123;</span><br><span class="line">            //如果能对比成功，说明登陆成功</span><br><span class="line"></span><br><span class="line">            LambdaQueryWrapper&lt;User&gt; queryWrapper = new LambdaQueryWrapper();</span><br><span class="line">            queryWrapper.eq(User::getPhone,phone);</span><br><span class="line"></span><br><span class="line">            User user = userService.getOne(queryWrapper);</span><br><span class="line">            if (user == null)&#123;</span><br><span class="line">                //判断当前手机号对应的用户是否为新用户，如果是新用户就自动完成注册</span><br><span class="line">                user = new User();</span><br><span class="line">                user.setPhone(phone);</span><br><span class="line">                user.setStatus(1);</span><br><span class="line">                userService.save(user);</span><br><span class="line">            &#125;</span><br><span class="line">            session.setAttribute(&quot;user&quot;,user.getId());</span><br><span class="line">            return R.success(user);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">        return R.error(&quot;登陆失败&quot;);</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<p>这里只是学习运用一下mybatisplus的知识，后台管理层开发就到这里啦！！</p>

</article>
    
    <div class="trm-reward">
        
            <span class="trm-reward-btn trm-glow" onclick='var qr = document.getElementById("qr"); qr.style.display = (qr.style.display === "none") ? "block" : "none";'>
                <i class="iconfont fas fa-hand-holding-usd"></i>
            </span>
        
        <p class="trm-reward-comment">I'm so cute. Please give me money.</p>
        <div id="qr" style="display:none;">
            
                <div style="display:inline-block">
                    <a rel="noopener noreferrer" href='\img\QRCode.jpg' target='_blank' >
                       <img src="/myblog/%5Cimg%5CQRCode.jpg" alt="微信" loading="lazy">
                    </a>
                    <p>微信</p>
                </div>
            
                <div style="display:inline-block">
                    <a rel="noopener noreferrer" href='\img\Alipay.jpg' target='_blank' >
                       <img src="/myblog/%5Cimg%5CAlipay.jpg" alt="支付宝" loading="lazy">
                    </a>
                    <p>支付宝</p>
                </div>
            
        </div>
    </div>

    

</div>
<div id="post-next-prev" class="row">
    <div class="col-lg-12">
        <!-- title -->
        <h5 class="trm-title-with-divider">
            其他文章
            <span data-number="02"></span>
        </h5>
    </div>
    
        <div class="col-lg-6">
    <div class="trm-blog-card trm-scroll-animation" data-scroll data-scroll-offset="40">
        <a href="/myblog/2023/07/24/%E5%AF%B9CHATGPT%E7%9A%84%E7%90%86%E8%A7%A3/" class="trm-cover-frame trm-anima-link">
            
            
                <img alt="cover" class="no-fancybox" src="/myblog/img/block.jpg">
            
        </a>
        
        <div class="trm-card-descr">
            <div class="trm-label trm-category trm-mb-20">
                <a href=" /myblog/categories/learn-and-imitate/">
                    learn and imitate
                </a>
            </div>
            <h5>
                <a href="/myblog/2023/07/24/%E5%AF%B9CHATGPT%E7%9A%84%E7%90%86%E8%A7%A3/" class="trm-anima-link">
                    对CHATGPT的理解
                </a>
            </h5>
            <div class="trm-divider trm-mb-20 trm-mt-20"></div>
            <ul class="trm-card-data trm-label">
                <li>23/07/24</li>
                <li>07:49</li>
                
                
            </ul>
        </div>
    </div>
</div>
    
    
        <div class="col-lg-6">
    <div class="trm-blog-card trm-scroll-animation" data-scroll data-scroll-offset="40">
        <a href="/myblog/2023/07/19/%E5%AD%A6%E4%BC%9A%E4%BD%BF%E7%94%A8Git/" class="trm-cover-frame trm-anima-link">
            
            
                <img alt="cover" class="no-fancybox" src="/myblog/img/block.jpg">
            
        </a>
        
        <div class="trm-card-descr">
            <div class="trm-label trm-category trm-mb-20">
                <a href=" /myblog/categories/Git-summarize/">
                    Git summarize
                </a>
            </div>
            <h5>
                <a href="/myblog/2023/07/19/%E5%AD%A6%E4%BC%9A%E4%BD%BF%E7%94%A8Git/" class="trm-anima-link">
                    学会使用Git
                </a>
            </h5>
            <div class="trm-divider trm-mb-20 trm-mt-20"></div>
            <ul class="trm-card-data trm-label">
                <li>23/07/19</li>
                <li>20:05</li>
                
                
            </ul>
        </div>
    </div>
</div>
    
</div>

    



                    <div class="trm-divider footer-divider"></div>

                    <!-- footer -->
                    <footer class="trm-scroll-animation" data-scroll data-scroll-offset="50">

    
        <div class="trm-footer-item">
            <a rel="noopener" href="https://beian.miit.gov.cn/" target="_blank"></a>
        </div>
    

    

    
        <div class="trm-footer-item">
            <span>
                由 <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> 驱动 v6.3.0
            </span>
            <span class="footer-separator" data-separator=" | "></span>
            <span> 
                主题 - 
                <a rel="noopener" href='https://github.com/MaLuns/hexo-theme-async' target='_blank'>Async</a>
                v2.0.9
            </span>
        </div>
      

    
        <div class="trm-footer-item">
            博客已萌萌哒运行 <span id="since" class="trm-accent-color"></span> 天
        </div>
     

    
        <div class="trm-footer-item">
            Hosted by <a href="https://github.com" rel="noopener" target="_blank">Github Pages</a>
        </div>
     
</footer>

<script>
    function show_date_time () {
        var BirthDay = new Date("07/15/2023 17:57:32");
        var today = new Date();
        var timeold = (today.getTime() - BirthDay.getTime());
        var msPerDay = 24 * 60 * 60 * 1000
        var day = Math.floor(timeold / msPerDay)
        since.innerHTML = day
    }
    show_date_time()
</script>
 
                    <!-- footer end -->

                </div>
            </div>
        </div>
    </div>
</div>
            <!-- body end -->

            <div class="trm-fixed-container" data-scroll data-scroll-sticky data-scroll-target=".locomotive-scroll__sticky-target" data-scroll-offset="-10">
    
        <div class="trm-fixed-btn" data-title="阅读模式" onclick="asyncFun.switchReadMode()">
            <i class="iconfont fas fa-book-reader"></i>
        </div>
    
    
    <div id="trm-back-top" class="trm-fixed-btn" data-title="回到顶部">
        <i class="iconfont fas fa-arrow-up"></i>
    </div>
</div>
          </div>
        </div>
      </div>
      <!-- scroll container end -->

  </div>
  <!-- app wrapper end -->

  
  <!-- Plugin -->




    
    
<script src="https://unpkg.com/locomotive-scroll@4.1.4/dist/locomotive-scroll.min.js"></script>

    
<script src="https://unpkg.com/@fancyapps/ui@4.0/dist/fancybox.umd.js"></script>

    

    
        <script src="/myblog/js/plugins/typing.js?v=2.0.9"></script>
    

    

    <!-- 数学公式 -->
    

    <!-- 评论插件 -->
    
        

        
    



<!-- CDN -->


    

    

    




    <!-- Service Worker -->
    
    <!-- baidu push -->
    


<script id="async-script" src="/myblog/js/main.js?v=2.0.9"></script>

</body>

</html>